﻿
(function (jQuery) {

    jQuery.fn.awShowcase = function (options) {

        // Default configuration properties
        var defaults =
		{
		    content_width: 700,
		    content_height: 470,
		    fit_to_parent: false,
		    auto: false,
		    interval: 3000,
		    continuous: false,
		    loading: true,
		    tooltip_width: 200,
		    tooltip_icon_width: 32,
		    tooltip_icon_height: 32,
		    tooltip_offsetx: 18,
		    tooltip_offsety: 0,
		    arrows: true,
		    buttons: true,
		    btn_numbers: false,
		    keybord_keys: false,
		    mousetrace: false,
		    pauseonover: true,
		    stoponclick: true,
		    transition: 'hslide',
		    transition_delay: 300,
		    transition_speed: 500,
		    show_caption: 'onload',
		    thumbnails: false,
		    thumbnails_position: 'outside-last',
		    thumbnails_direction: 'vertical',
		    thumbnails_slidex: 0,
		    dynamic_height: false,
		    speed_change: false,
		    viewline: false,
		    fullscreen_width_x: 15,
		    custom_function: null
		};

        // *****************
        // SET UP THE PLUGIN
        // *****************

        // Declare and set up some important variables
        options = jQuery.extend(defaults, options);
        var current_id = 0;
        var previous_id = 0;
        var break_loop = false;
        var pause_loop = false;
        var myInterval = null;
        var showcase = jQuery(this);
        var showcase_width = options.content_width;
        var animating = false;
        // Viewline specific variables
        var content_viewline_width = 10000;
        var animation_distance = 0;
        var old_animation_distance = 0;
        var remaining_width = 0;

        // Set up the content wrapper
        var content_container = jQuery(document.createElement('div'))
			.css('overflow', 'hidden')
			.css('position', 'relative')
			.addClass('showcase-content-container')
			.prependTo(showcase);

        // Set up the showcase for hundred percent width
        if (options.fit_to_parent) {
            showcase_width = jQuery(showcase).width() + options.fullscreen_width_x;
        }

        // Set up the showcase for Viewline Mayhem
        if (options.viewline) {
            options.thumbnails = false;
            options.dynamic_height = false;
            content_container.css('width', content_viewline_width);
            showcase.css('overflow', 'hidden');
            $('.showcase-arrow-previous').hide();
        }

        // Set up content and create the content and thumbnail array
        var contentArray = [];
        var thumbnailArray = [];
        var content_count = 0;
        showcase.children('.showcase-slide').each(function () {
            // Get content
            var object = jQuery(this);
            content_count++;

            // If thumbnails are activated
            if (options.thumbnails) {
                // Get thumbnail and put in array
                var thumb = object.find('.showcase-thumbnail');
                thumbnailArray.push(thumb);
                thumb.remove();
            }

            // Set content width and height
            var object_width = object.find('.showcase-content').children().width();
            var object_height = object.find('.showcase-content').children().height();

            // Add content html in array and remove it from DOM
            contentArray.push(object.html());
            object.remove();

            // Get correct content
            var new_object = getContent(content_count - 1);
            if (options.viewline || content_count === 1) { content_container.append(new_object); }

            // Viewline setup
            if (options.viewline) {
                new_object.css('position', 'relative');
                new_object.css('float', 'left');
                new_object.css('width', object_width);
            }

            // Set content and content container load height
            if (options.dynamic_height) {
                new_object.css('height', object_height);
                if (content_count === 1) { content_container.css('height', object_height); }
            }
            else {
                new_object.css('height', options.content_height);
                if (content_count === 1) { content_container.css('height', options.content_height); }
            }

            if (options.viewline || content_count === 1) {
                displayAnchors(new_object);
                displayCaption(new_object);

                if (options.show_caption === 'show') {
                    jQuery(new_object).find('.showcase-caption').show();
                }
            }
        });

        // Declare and set up the thumbnail wrapper
        var thumb_wrapper;
        var thumbnailStretch = 0;
        var thumbnailsPerPage = 0;
        if (options.thumbnails) {
            // Create wrapper
            thumb_container = jQuery('<div />');
            thumb_restriction = jQuery('<div />');
            thumb_wrapper = jQuery('<div />');

            // Add content to thumbnail wrapper
            for (i = thumbnailArray.length - 1; i >= 0; --i) {
                var thumbnail = jQuery(thumbnailArray[i]).css({ 'overflow': 'hidden' });
                thumbnail.attr('id', 'showcase-thumbnail-' + i);
                thumbnail.addClass((i === 0) ? 'active' : '');
                thumbnail.click(function (a, b) {
                    // This function is used to extract the correct i value on click
                    return function () {
                        // Disable auto change on click
                        if (myInterval) { pause_loop = true; clearInterval(myInterval); }
                        changeContent(a, b);
                    };
                } (i, ''));
                thumb_wrapper.prepend(thumbnail);
            }

            // Style and position thumbnail container and content wrapper
            // + insert thumbnail container
            if (options.thumbnails_position === 'outside-first' || options.thumbnails_position === 'outside-last') {
                if (options.thumbnails_direction !== 'horizontal') {
                    /* outside & vertical */
                    content_container.css('float', 'left');
                    content_container.css('width', options.content_width);
                    thumb_container.css('float', 'left');
                    thumb_container.css('height', options.content_height);
                }
                else {
                    /* outside & horizontal */
                    jQuery(thumb_wrapper).find('.showcase-thumbnail').css('float', 'left');
                    //jQuery(thumb_wrapper).append(jQuery('<div />').addClass('clear'));
                }

                if (options.thumbnails_position === 'outside-last') {
                    /* outside-last */
                    showcase.append(thumb_container);
                    if (options.thumbnails_direction !== 'horizontal') { showcase.append(jQuery('<div />').addClass('clear')); }
                }
                else {
                    /* outside-first */
                    showcase.prepend(thumb_container);
                    if (options.thumbnails_direction !== 'horizontal') { showcase.append(jQuery('<div />').addClass('clear')); }
                }
            }
            else {
                thumb_container.css({ 'position': 'absolute', 'z-index': 20 });
                if (options.thumbnails_direction === 'horizontal') {
                    /* inside & horizontal */
                    thumb_container.css({ 'left': 0, 'right': 0 });
                    jQuery(thumb_wrapper).find('.showcase-thumbnail').css('float', 'left');
                    jQuery(thumb_wrapper).append(jQuery('<div />').addClass('clear'));

                    /* inside first */
                    if (options.thumbnails_position === 'inside-first') { thumb_container.css('top', 0); }
                    /* inside last */
                    else { thumb_container.css('bottom', 0); }
                }
                else {
                    /* inside & vertical */
                    thumb_container.css({ 'top': 0, 'bottom': 0 });
                    /* inside first */
                    if (options.thumbnails_position === 'inside-first') { thumb_container.css('left', 0); }
                    /* inside last */
                    else { thumb_container.css('right', 0); }
                }
                content_container.prepend(thumb_container);
            }

            // Add class and style to thumbnail container
            thumb_container.addClass('showcase-thumbnail-container');
            thumb_container.css('overflow', 'hidden');

            // Add class and style to thumbnail restriction
            thumb_restriction.addClass('showcase-thumbnail-restriction');
            thumb_restriction.css({ 'overflow': 'hidden', 'position': 'relative' });
            if (options.thumbnails_direction === 'horizontal') { thumb_restriction.css({ 'float': 'left' }); }

            // Add class and style to thumbnail wrapper 
            thumb_wrapper.addClass('showcase-thumbnail-wrapper');
            if (options.thumbnails_direction === 'horizontal') { thumb_wrapper.addClass('showcase-thumbnail-wrapper-horizontal'); }
            else { thumb_wrapper.addClass('showcase-thumbnail-wrapper-vertical'); }
            thumb_wrapper.css('position', 'relative');

            // Append wrapper and restriction
            thumb_restriction.append(thumb_wrapper);
            thumb_container.append(thumb_restriction);

            // Add backward button
            var buttonBackward = jQuery('<div class="showcase-thumbnail-button-backward" />');
            if (options.thumbnails_direction !== 'horizontal') {
                buttonBackward.html('<span class="showcase-thumbnail-vertical"><span>Up</span></span>');
            }
            else {
                buttonBackward.css({ 'float': 'left' });
                buttonBackward.html('<span class="showcase-thumbnail-horizontal"><span>Left</span></span>');
            }
            buttonBackward.click(function () { slideThumbnailWrapper('backward', false, true); });
            thumb_container.prepend(buttonBackward);

            // Add forward button
            var buttonForward = jQuery('<div class="showcase-thumbnail-button-forward" />');
            if (options.thumbnails_direction !== 'horizontal') {
                buttonForward.html('<span class="showcase-thumbnail-vertical"><span>Down</span></span>');
            }
            else {
                buttonForward.css({ 'float': 'left' });
                buttonForward.html('<span class="showcase-thumbnail-horizontal"><span>Right</span></span>');
            }
            buttonForward.click(function () { slideThumbnailWrapper('forward', false, true); });
            thumb_container.append(buttonForward);

            // Set the number of thumbnails per page.
            var thumbnailVisibleStretch = 0;
            if (options.thumbnails_direction !== 'horizontal') {
                thumbnailVisibleStretch = getElementHeight(thumb_wrapper, false);
                thumbnailVisibleStretch += (getElementHeight(buttonBackward)) + (getElementHeight(buttonForward));
                while (thumbnailVisibleStretch < options.content_height) {
                    thumbnailVisibleStretch += getElementHeight(jQuery(thumbnailArray[0]));
                    thumbnailsPerPage++;
                }
            }
            else {
                thumbnailVisibleStretch = getElementWidth(thumb_wrapper, false);
                thumbnailVisibleStretch += (getElementWidth(buttonBackward)) + (getElementWidth(buttonForward));

                while (thumbnailVisibleStretch < showcase_width) {
                    thumbnailVisibleStretch += getElementWidth(jQuery(thumbnailArray[0]));
                    thumbnailsPerPage++;
                }
            }

            // Hide buttons if they're not necessary
            if (thumbnailsPerPage + 1 > thumbnailArray.length) {
                if (options.thumbnails_direction !== 'horizontal') {
                    thumb_restriction.css('margin-top', getElementHeight(buttonBackward));
                }
                else {
                    thumb_restriction.css('margin-left', getElementWidth(buttonBackward));
                }
                buttonBackward.hide();
                buttonForward.hide();
            }

            // Set thumbnail restriction height or width
            if (options.thumbnails_direction !== 'horizontal') {
                var buttonsHeight = (getElementHeight(buttonBackward)) + (getElementHeight(buttonForward));
                thumb_restriction.css('height', options.content_height - buttonsHeight);
            }
            else {
                var buttonsWidth = (getElementWidth(buttonBackward)) + (getElementWidth(buttonForward));
                thumb_restriction.css('width', showcase_width - buttonsWidth);
            }

            // Set thumbnail wrapper width
            if (options.thumbnails_direction === 'horizontal') {
                jQuery('.showcase-thumbnail').each(function () { thumbnailStretch += getElementWidth(jQuery(this)); });
                thumb_wrapper.css('width', thumbnailStretch);
            }
            else { jQuery('.showcase-thumbnail').each(function () { thumbnailStretch += getElementHeight(jQuery(this)); }); }
        }

        // Set showcase width and height
        if (options.thumbnails && options.thumbnails_position.indexOf("outside") !== -1 && options.thumbnails_direction !== 'horizontal' && !options.viewline) {
            showcase.css('width', showcase_width + getElementWidth(thumb_wrapper, true, false));
        }
        else if (!options.fit_to_parent) { showcase.css('width', showcase_width); }

        // Turn on/off auto slide
        if (content_count > 1 && options.auto) { myInterval = window.setInterval(autoChange, options.interval); }

        // Pause auto on mouse over
        if (options.auto && options.pauseonover) {
            showcase.mouseenter(function () { break_loop = true; clearInterval(myInterval); });
            showcase.mouseleave(function () {
                if (!pause_loop) {
                    break_loop = false; myInterval = window.setInterval(autoChange, options.interval);
                }
            });
        }

        // Adding navigation arrows
        if (options.arrows && content_count > 1) {
            // Left arrow
            jQuery(document.createElement('div'))
				.addClass('showcase-arrow-previous')
				.prependTo(showcase)
				.click(function () {
				    // Disable auto change on click
				    if (myInterval) {
				        if (options.stoponclick) { pause_loop = true; }
				        clearInterval(myInterval);
				    }
				    changeContent((current_id === 0) ? content_count - 1 : parseInt(current_id) - 1, 'previous');
				});
            // Right arrow
            jQuery(document.createElement('div'))
				.addClass('showcase-arrow-next')
				.prependTo(showcase)
				.click(function () {
				    // Disable auto change on click
				    if (myInterval) {
				        if (options.stoponclick) { pause_loop = true; }
				        clearInterval(myInterval);
				    }
				    changeContent(current_id + 1, 'next');
				});

            if (options.viewline) { $('.showcase-arrow-previous').hide(); }
        }

        // Adding navigation buttons
        if (options.buttons && content_count > 1) {
            // Create button wrapper
            jQuery(document.createElement('div'))
				.css('clear', 'both')
				.addClass('showcase-button-wrapper')
				.appendTo(showcase);
            i = 0;
            // Add button for each content
            while (i < content_count) {
                jQuery(document.createElement('span'))
					.attr('id', 'showcase-navigation-button-' + i)
					.addClass((i === 0) ? 'active' : '')
                // Add numbers or unicode
					.html((options.btn_numbers) ? parseInt(i) + 1 : '&#9679;')
					.click(function (a, b) {
					    // This function is used to extract the correct i value on click
					    return function () {
					        // Disable auto change on click
					        if (myInterval) {
					            if (options.stoponclick) { pause_loop = true; }
					            clearInterval(myInterval);
					        }
					        changeContent(a, b);
					    };
					} (i, ''))
					.appendTo(jQuery(showcase).find('.showcase-button-wrapper'));
                i++;
            }
        }

        // Activating the keybord arrow keys
        if (options.keybord_keys) {
            jQuery(document).keydown(function (e) {
                // Disable auto change on click
                if (options.stoponclick) { pause_loop = true; }
                if (myInterval) clearInterval(myInterval);

                // Left arrow
                if (e.keyCode === 37) {
                    changeContent((current_id === 0) ? content_count - 1 : parseInt(current_id) - 1, 'previous');
                }

                // Right arrow
                if (e.keyCode === 39) {
                    changeContent((current_id === content_count - 1) ? 0 : parseInt(current_id) + 1, 'next');
                }
            });
        }


        // *************
        // THE FUNCTIONS
        // *************

        // Returns the specified content (by array id)
        function getContent(id) {

            var new_content = jQuery(document.createElement('div'))
				.attr('id', 'showcase-content-' + id)
				.css('overflow', 'hidden')
				.css('position', 'absolute')
				.addClass('showcase-content')
				.html(contentArray[id]);

            // Set content width
            if (!options.viewline) { new_content.css('width', options.content_width); }

            // Position the content wrapper if showcase width is set to hundred percent
            if (options.fit_to_parent && !options.viewline) { new_content.css('left', (showcase_width / 2) - options.content_width / 2); }

            return new_content;
        }

        // Function that runs when content is set to change automatically
        function autoChange() {

            // Set next content id
            var nextID = parseInt(current_id) + 1;
            // If the next id is outside the array and continuous is set to true set the id to 0
            if (nextID === content_count && options.continuous) { nextID = 0; }
            // If continuous is set to false break the auto change
            else if (nextID === content_count && !options.continuous) { break_loop = true; clearInterval(myInterval); }
            // Don't change the content if the auto change is broken
            if (!break_loop) { changeContent(nextID, 'next'); }
        }

        // Changes the content (no explanation/comments needed :)
        function changeContent(id, direction) {

            // If the next content isn't the current content
            if (current_id !== id && !animating) {

                var obj;
                var obj2;
                var delay = 0;
                var i;

                // Set left/right position if showcase is set to full width
                var lrpos = (options.fit_to_parent) ? (showcase_width / 2) - (options.content_width / 2) : 0;

                // If we want to display the next content
                if ((id > current_id && direction !== 'previous') || direction === 'next') {

                    if (options.viewline) {

                        if (current_id < content_count - 1) {

                            // Prevent uggly transitions
                            if (!options.speed_change) { animating = true; }

                            // BugFix
                            updateContentViewlineWidth();

                            // Pause Autoplay
                            if (options.pauseonover) { window.clearInterval(myInterval); }

                            // First we check if the content will fill the screen after animation.
                            remaining_width = 0;

                            // Loop trough the content array to find out 
                            // the total width for the content that remains.
                            for (i = current_id + 1, len = content_count; i < len; ++i) {
                                obj = addedContentArray[i];
                                remaining_width += obj.find('.showcase-content').children().width();
                            }

                            // If the remaining width is wider than the browser window.
                            if (remaining_width > showcase_width) {
                                old_animation_distance = animation_distance;
                                animation_distance -= addedContentArray[current_id].find('.showcase-content').children().width();
                            }
                            else if ($('.showcase-arrow-next').is(':visible')) {
                                old_animation_distance = animation_distance;
                                animation_distance = -(content_viewline_width - (remaining_width + (showcase_width - remaining_width)));
                                $('.showcase-arrow-next').fadeOut(300);
                            }

                            content_container.animate({ left: animation_distance + 'px' }, options.transition_speed, function () { animating = false; });

                            // Change current content id (if content is finished)
                            if ($('.showcase-arrow-next').is(':visible')) { current_id++; }

                            $('.showcase-arrow-previous').fadeIn(300);
                        }
                    }
                    else {

                        // Prevent uggly transitions
                        if (!options.speed_change) { animating = true; }

                        // Get current and next content element
                        obj = jQuery(showcase).find('#showcase-content-' + parseInt(current_id));
                        obj2 = getContent(id);

                        // Append next element and set height
                        content_container.append(obj2);
                        if (options.dynamic_height) { obj2.css('height', obj2.find('.showcase-content').children().height()); }
                        else { obj2.css('height', options.content_height); }

                        // Animate height first if next content is not as high
                        if (obj.find('.showcase-content').children().height() > obj2.find('.showcase-content').children().height() && options.dynamic_height) {

                            content_container.stop(true, true).animate({ height: obj2.find('.showcase-content').children().height() }, 200);
                            delay = 100;
                        }

                        // Animate current element
                        if (options.transition === 'hslide') {

                            jQuery(obj).delay(delay).animate({ left: -(options.content_width) }, options.transition_speed + options.transition_delay, function () { obj.remove(); });
                        }
                        else if (options.transition === 'vslide') {

                            jQuery(obj).delay(delay).animate({ top: -(options.content_height) }, options.transition_speed + options.transition_delay, function () { obj.remove(); });
                        }
                        else {

                            jQuery(obj).delay(delay).fadeOut(options.transition_speed, function () { obj.remove(); });
                        }

                        // This will hide them, not display them :)
                        displayAnchors(obj, true);
                        displayCaption(obj, true);

                        // Animate next element
                        if (options.transition === 'hslide') {

                            obj2.css('left', showcase_width);
                            jQuery(obj2).delay(delay).animate({ left: lrpos }, options.transition_speed, function () {
                                displayAnchors(obj2);
                                displayCaption(obj2);
                                afterAnimation(obj2);
                            }
							);
                        }
                        else if (options.transition === 'vslide') {

                            obj2.css('top', showcase.height());
                            jQuery(obj2).delay(delay).animate({ top: '0px' }, options.transition_speed, function () {
                                displayAnchors(obj2);
                                displayCaption(obj2);
                                afterAnimation(obj2);
                            }
							);
                        }
                        else {

                            obj2.css('left', lrpos);
                            obj2.css('display', 'none');
                            jQuery(obj2).delay(delay).fadeIn(options.transition_speed, function () {
                                displayAnchors(obj2);
                                displayCaption(obj2);
                                afterAnimation(obj2);
                            }
							);
                        }
                    }
                }
                // If we want to display the previous content
                else if (id < current_id || direction === 'previous') {

                    if (options.viewline) {

                        if (current_id !== 0) {

                            // Prevent uggly transitions
                            if (!options.speed_change) { animating = true; }

                            // BugFix
                            updateContentViewlineWidth();

                            // Pause Autoplay
                            if (options.pauseonover) { window.clearInterval(myInterval); }

                            content_container.animate({ left: old_animation_distance + 'px' }, options.transition_speed, function () { animating = false; });

                            // Set animation distance
                            animation_distance = old_animation_distance;

                            // Change current content id
                            current_id--;

                            if (current_id === 0) { $('.showcase-arrow-previous').fadeOut(300); }

                            // Set old distance
                            old_id = current_id - 1;
                            sub_width = jQuery(addedContentArray[old_id]).width();
                            old_animation_distance = old_animation_distance + sub_width;
                        }

                        $('.showcase-arrow-next').fadeIn(300);
                    }
                    else {

                        // Prevent uggly transitions
                        if (!options.speed_change) { animating = true; }

                        // Get current and next content element
                        obj = jQuery(showcase).find('#showcase-content-' + parseInt(current_id));
                        obj2 = getContent(id);

                        // Append next element and set height
                        content_container.append(obj2);
                        if (options.dynamic_height) { obj2.css('height', obj2.find('.showcase-content').children().height()); }
                        else { obj2.css('height', options.content_height); }

                        // Animate height first if next content is not as high
                        if (obj.find('.showcase-content').children().height() > obj2.find('.showcase-content').children().height() && options.dynamic_height) {

                            content_container.stop(true, true).animate({ height: obj2.find('.showcase-content').children().height() }, 200);
                            delay = 100;
                        }

                        // Animate current element
                        if (options.transition === 'hslide') {

                            jQuery(obj).delay(delay).animate({
                                left: (showcase_width) + 'px'
                            }, options.transition_speed + options.transition_delay, function () {
                                displayAnchors(obj, true);
                                displayCaption(obj, true);
                                obj.remove();
                            });
                        }
                        else if (options.transition === 'vslide') {

                            jQuery(obj).delay(delay).animate({
                                top: (options.content_height) + 'px'
                            }, options.transition_speed + options.transition_delay, function () {
                                displayAnchors(obj, true);
                                displayCaption(obj, true);
                                obj.remove();
                            });
                        }
                        else {

                            jQuery(obj).delay(delay).fadeOut(options.transition_speed, function () {
                                displayAnchors(obj, true);
                                displayCaption(obj, true);
                                obj.remove();
                            });
                        }

                        // Animate next element
                        if (options.transition === 'hslide') {
                            obj2.css('left', '-' + options.content_width + 'px');
                            jQuery(obj2).delay(delay).animate({
                                left: lrpos
                            }, options.transition_speed, function () {
                                displayAnchors(obj2);
                                displayCaption(obj2);
                                afterAnimation(obj2);
                            });
                        }
                        else if (options.transition === 'vslide') {
                            obj2.css('top', '-' + showcase.height() + 'px');
                            jQuery(obj2).delay(delay).animate({
                                top: '0px'
                            }, options.transition_speed, function () {
                                displayAnchors(obj2);
                                displayCaption(obj2);
                                afterAnimation(obj2);
                            });
                        }
                        else {
                            obj2.css('left', lrpos);
                            obj2.css('display', 'none');
                            jQuery(obj2).delay(delay).fadeIn(options.transition_speed, function () {
                                displayAnchors(obj2);
                                displayCaption(obj2);
                                afterAnimation(obj2);
                            });
                        }
                        content_container.append(obj2);
                    }
                }

                if (!options.viewline) {
                    // Change previous and current content id
                    previous_id = current_id;
                    current_id = id;

                    // Slide thumbnail wrapper
                    if (options.thumbnails) {
                        if ((current_id > previous_id && direction !== 'previous') || direction === 'next') {
                            slideThumbnailWrapper('forward', true);
                        }
                        else if (current_id < previous_id || direction === 'previous') {
                            slideThumbnailWrapper('backward', true);
                        }
                    }

                    // Change click handlers for arrows
                    if (options.arrows) {
                        jQuery(showcase).find('.showcase-arrow-previous')
							.unbind('click')
							.click(function () {
							    if (myInterval) {
							        if (options.stoponclick) { pause_loop = true; }
							        clearInterval(myInterval);
							    }
							    changeContent((current_id === 0) ? content_count - 1 : parseInt(current_id) - 1, 'previous');
							});
                        jQuery(showcase).find('.showcase-arrow-next')
							.unbind('click')
							.click(function () {
							    if (myInterval) {
							        if (options.stoponclick) { pause_loop = true; }
							        clearInterval(myInterval);
							    }
							    changeContent((current_id === content_count - 1) ? 0 : parseInt(current_id) + 1, 'next');
							});
                    }

                    // Change active class for thumbnails
                    if (options.thumbnails) {
                        i = 0;
                        showcase.find('.showcase-thumbnail').each(function () {
                            var object = jQuery(this);
                            object.removeClass('active');
                            if (i === current_id) { object.addClass('active'); }
                            i++;
                        });
                    }

                    // If caption is set to 'show'
                    if (options.show_caption === 'show') { jQuery(obj2).find('.showcase-caption').show(); }
                }

                // Change active class for buttons
                if (options.buttons) {
                    i = 0;
                    showcase.find('.showcase-button-wrapper span').each(function () {
                        var object = jQuery(this);
                        object.removeClass('active');
                        if (i === current_id) { object.addClass('active'); }
                        i++;
                    });
                }

                // A function that runs on content change, if it exists.
                if (typeof options.custom_function == 'function') {
                    options.custom_function();
                }
            }
        }

        function afterAnimation(obj) {
            if (options.dynamic_height) { content_container.stop(true, true).animate({ height: obj.find('.showcase-content').children().height() }, 200); }
            animating = false;
        }

        // Slide thumbnail wrapper
        var thumbnailSlidePosition = 0;
        function slideThumbnailWrapper(direction, check, backwardforward) {
            var doTheSlide = true;
            var thumbnailHeightOrWidth = getElementHeight(jQuery(thumb_wrapper).find('.showcase-thumbnail'));
            if (options.thumbnails_direction === 'horizontal') {
                thumbnailHeightOrWidth = getElementWidth(jQuery(thumb_wrapper).find('.showcase-thumbnail'));
            }
            var multiplySlidePosition = 1;

            // Set slide x
            if (options.thumbnails_slidex === 0) { options.thumbnails_slidex = thumbnailsPerPage; }

            // Check if we need to do the slide
            if (check) {
                var thumbnailSlidePositionCopy = thumbnailSlidePosition;
                var thumbnailsScrolled = 0;
                while (thumbnailSlidePositionCopy < 0) {
                    if (options.thumbnails_direction === 'horizontal') {
                        thumbnailSlidePositionCopy += getElementWidth(jQuery(thumbnailArray[0]));
                    }
                    else {
                        thumbnailSlidePositionCopy += getElementHeight(jQuery(thumbnailArray[0]));
                    }
                    thumbnailsScrolled++;
                }

                var firstVisible = thumbnailsScrolled;
                var lastVisible = thumbnailsPerPage + thumbnailsScrolled - 1;

                // Check if the next active thumbnail is outside the visible area
                if (current_id >= firstVisible && current_id <= lastVisible) { doTheSlide = false; }

                // If the next active thumbnail is far away..
                var distance;
                if ((current_id - lastVisible) > options.thumbnails_slidex) {
                    distance = current_id - lastVisible;

                    while (distance > options.thumbnails_slidex) {
                        distance -= options.thumbnails_slidex;
                        multiplySlidePosition++;
                    }
                }
                else if ((firstVisible - current_id) > options.thumbnails_slidex) {
                    distance = firstVisible - current_id;

                    while (distance > options.thumbnails_slidex) {
                        distance -= options.thumbnails_slidex;
                        multiplySlidePosition++;
                    }
                }
                else { multiplySlidePosition = 1; }
            }

            if (direction === 'forward' && doTheSlide) {
                if (options.thumbnails_direction === 'vertical' && options.content_height < (thumbnailStretch + thumbnailSlidePosition)) {
                    thumbnailSlidePosition -= thumbnailHeightOrWidth * (options.thumbnails_slidex * multiplySlidePosition);
                }
                else if (options.thumbnails_direction === 'horizontal' && options.content_width < (thumbnailStretch + thumbnailSlidePosition)) {
                    thumbnailSlidePosition -= thumbnailHeightOrWidth * (options.thumbnails_slidex * multiplySlidePosition);
                }
                else if (current_id === 0) {
                    if (!backwardforward) { thumbnailSlidePosition = 0; }
                }
                if (options.thumbnails_direction === 'horizontal') { thumb_wrapper.animate({ left: thumbnailSlidePosition }, 300); }
                else { thumb_wrapper.animate({ top: thumbnailSlidePosition }, 300); }
            }
            else if (doTheSlide) {
                if (thumbnailSlidePosition < 0) {
                    thumbnailSlidePosition += thumbnailHeightOrWidth * (options.thumbnails_slidex * multiplySlidePosition);
                }
                else if (current_id === content_count - 1) {
                    if (!backwardforward) {
                        thumbnailSlidePosition -= thumbnailHeightOrWidth * (options.thumbnails_slidex * multiplySlidePosition);
                    }
                }
                else { thumbnailSlidePosition = 0; }
                if (options.thumbnails_direction === 'horizontal') { thumb_wrapper.animate({ left: thumbnailSlidePosition }, 300); }
                else { thumb_wrapper.animate({ top: thumbnailSlidePosition }, 300); }
            }
        }

        // Displays the caption
        function displayCaption(container, fadeOut) {
            var caption = container.find('.showcase-caption');
            if (!fadeOut) {
                if (options.show_caption === 'onload') { caption.fadeIn(300); }
                else if (options.show_caption === 'onhover') {
                    jQuery(container).mouseenter(function () {
                        caption.fadeIn(300);
                    });

                    jQuery(container).mouseleave(function () {
                        caption.stop(true, true).fadeOut(100);
                    });
                }
            }
            else { caption.stop(true, true).fadeOut(300); }
        }

        // Displays the anchors in the current slide
        function displayAnchors(container, fadeOut) {
            // Get each anchor tooltip
            container.find('.showcase-tooltips a').each(function () {
                if (!fadeOut) {
                    // Get coordinates
                    var coords = jQuery(this).attr('coords');
                    coords = coords.split(',');

                    // Style and position anchor
                    jQuery(this).addClass('showcase-plus-anchor');
                    jQuery(this).css('position', 'absolute');
                    jQuery(this).css('display', 'none');
                    jQuery(this).css('width', options.tooltip_icon_width);
                    jQuery(this).css('height', options.tooltip_icon_height);
                    jQuery(this).css('left', parseInt(coords[0]) - (parseInt(options.tooltip_icon_width) / 2));
                    jQuery(this).css('top', parseInt(coords[1]) - (parseInt(options.tooltip_icon_height) / 2));
                    var content = jQuery(this).html();
                    jQuery(this).mouseenter(function () {
                        animateTooltip(container, coords[0], coords[1], content);
                    });
                    jQuery(this).mouseleave(function () {
                        animateTooltip(container, coords[0], coords[1], content);
                    });
                    jQuery(this).html('');
                    jQuery(this).fadeIn(300);
                }
                else {
                    jQuery(this).stop(true, true).fadeOut(300);
                }
            });
        }

        // Controls the animation for the tooltips
        var tooltip = null;
        function animateTooltip(container, x, y, content) {
            // if tooltip is null (doesn't exsist)
            if (tooltip === null) {
                // Create the tooltip
                tooltip = jQuery(document.createElement('div'))
					.addClass('showcase-tooltip')
					.css('display', 'none')
					.css('position', 'absolute')
					.css('max-width', options.tooltip_width)
					.html(content);
                container.append(tooltip);

                // Position the tooltip (this is where we try not to display the tooltip outside the content wrapper)
                var tooltip_paddingx = parseInt(tooltip.css('padding-right')) * 2 + parseInt(tooltip.css('border-right-width')) * 2;
                var tooltip_paddingy = parseInt(tooltip.css('padding-bottom')) * 2 + parseInt(tooltip.css('border-bottom-width')) * 2;
                lastx = parseInt(x) + tooltip.width() + tooltip_paddingx;
                lasty = parseInt(y) + tooltip.height() + tooltip_paddingy;

                if (lastx < options.content_width) {
                    tooltip.css('left', parseInt(x) + parseInt(options.tooltip_offsetx));
                }
                else {
                    tooltip.css('left', (parseInt(x) - parseInt(options.tooltip_offsetx)) - (parseInt(tooltip.width()) + parseInt(options.tooltip_offsetx)));
                }

                if (lasty < options.content_height) {
                    tooltip.css('top', parseInt(y) + parseInt(options.tooltip_offsety));
                }
                else {
                    tooltip.css('top', (parseInt(y) - parseInt(options.tooltip_offsety)) - (parseInt(tooltip.height()) + parseInt(tooltip_paddingy)));
                }

                // Fade in the tooltip
                tooltip.fadeIn(400);
            }
            else {
                // Fade out the tooltip
                tooltip.fadeOut(400);
                // Remove it from the DOM
                tooltip.remove();
                // And set the variable to null
                tooltip = null;
            }
        }

        /* Returns the correct height for the element, including padding and borders. */
        function getElementHeight(el, incHeight, incMargin, incPadding, incBorders) {
            incHeight = typeof (incHeight) !== 'undefined' ? incHeight : true;
            incMargin = typeof (incMargin) !== 'undefined' ? incMargin : true;
            incPadding = typeof (incPadding) !== 'undefined' ? incPadding : true;
            incBorders = typeof (incBorders) !== 'undefined' ? incBorders : true;
            var elHeight = (incHeight) ? jQuery((el)).height() : 0;
            var elMargin = (incMargin) ? parseFloat(jQuery((el)).css('margin-top')) + parseFloat(jQuery(el).css('margin-bottom')) : 0;
            var elPadding = (incPadding) ? parseFloat(jQuery((el)).css('padding-top')) + parseFloat(jQuery(el).css('padding-bottom')) : 0;
            var elBorder = (incBorders) ? parseFloat(jQuery((el)).css('border-top-width')) + parseFloat(jQuery((el)).css('border-bottom-width')) : 0;
            elHeight += elMargin + elPadding + elBorder;
            return elHeight;
        }

        /* Returns the correct width for the element, including width, margin, padding and borders. */
        function getElementWidth(el, incWidth, incMargin, incPadding, incBorders) {
            incWidth = typeof (incWidth) !== 'undefined' ? incWidth : true;
            incMargin = typeof (incMargin) !== 'undefined' ? incMargin : true;
            incPadding = typeof (incPadding) !== 'undefined' ? incPadding : true;
            incBorders = typeof (incBorders) !== 'undefined' ? incBorders : true;
            var elWidth = (incWidth) ? jQuery((el)).width() : 0;
            var elMargin = (incMargin) ? parseFloat(jQuery((el)).css('margin-left')) + parseFloat(jQuery(el).css('margin-right')) : 0;
            var elPadding = (incPadding) ? parseFloat(jQuery((el)).css('padding-left')) + parseFloat(jQuery((el)).css('padding-right')) : 0;
            var elBorder = (incBorders) ? parseFloat(jQuery((el)).css('border-left-width')) + parseFloat(jQuery((el)).css('border-right-width')) : 0;
            elWidth += elMargin + elPadding + elBorder;
            return elWidth;
        }

        // Traces the mouse position (used for positioning anchors)
        if (options.mousetrace) {
            // Create the div tha displays the coordinates
            var mousetrace = jQuery(document.createElement('div'))
				.css('position', 'absolute')
				.css('top', '0')
				.css('background-color', '#fff')
				.css('color', '#000')
				.css('padding', '3px 5px')
				.css('x-index', '30')
				.html('X: 0 Y: 0');
            showcase.append(mousetrace);
            var offset = showcase.offset();

            // Print the coordinates
            content_container.mousemove(function (e) { mousetrace.html('X: ' + (e.pageX - offset.left) + ' Y: ' + (e.pageY - offset.top)); });
        }

        // Show all content on one page
        $('#awOnePageButton').click(function showInOnePage() {
            if ($('.view-page').is(':visible')) {
                var temp_container = jQuery(document.createElement('div'));
                temp_container.addClass('showcase-onepage');
                showcase.before(temp_container);

                // Disable auto change on click
                if (myInterval) { pause_loop = true; clearInterval(myInterval); }

                $(this).find('.view-page').hide();
                $(this).find('.view-slide').show();
                showcase.hide();

                $.each(contentArray, function (index, value) {
                    obj = getContent(index);
                    obj.css('position', 'relative');
                    temp_container.append(obj);

                    displayAnchors(obj);
                    displayCaption(obj);

                    if (options.dynamic_height) { obj.css('height', obj.find('.showcase-content').children().height()); }
                    else { obj.css('height', options.content_height); }
                });

                var clear = jQuery(document.createElement('div'));
                clear.addClass('clear');
                temp_container.append(clear);
            }
            else {
                $('.showcase-onepage').remove();
                $(this).find('.view-page').show();
                $(this).find('.view-slide').hide();
                showcase.show();
            }

            return false;
        });

        // The correct width is returned when all content is fully loaded.
        var addedContentArray = [];
        function updateContentViewlineWidth() {
            content_viewline_width = 0;
            content_container.children('div').each(function () {
                content_viewline_width += $(this).find('.showcase-content').children().width();
                addedContentArray.push($(this));
            });
        }

        // Remove loading class
        showcase.removeClass('showcase-load');
    };

})(jQuery);